﻿
Module Funciones
    Dim Random As New Random()
#Region "variables"
    Enum piezas As Byte
        blanco = 0
        negro = 1
        vacio = 2
        paso = 4
    End Enum
    Public Pieza() As String = {"blanco", "negro", ""}
    Dim fila() As String = {"", "8", "7", "6", "5", "4", "3", "2", "1"}
    Dim columna() As String = {"", "a", "b", "c", "d", "e", "f", "g", "h"}
#End Region

#Region "Random de indice"

    Public Function randomX() As Integer
        Dim Random As New Random()
        Return Random.Next(1, 8)
    End Function

    Public Function randomY() As Integer
        Dim Random As New Random()
        Return Random.Next(1, 8)
    End Function

#End Region

#Region "Random de Posicion"
    'determina un valor aleatorio de acuerdo al numero de indices
    Public Function randomPosicion() As String
        Dim Random As New Random()
        randomPosicion = columna(randomY) + fila(randomX)
        Return randomPosicion

    End Function
    'determina valor aleatorio de acuerdo a la concatenacion de los indices, por ejemplo la pos 1 2 lo convertiria en 12
    Public Function randomPosicionXY() As String
        Dim Random As New Random()
        Dim encontrado As Boolean = False
        Dim nroNoValido As String = "10,19,20,29,30,39,40,49,50,59,60,69,70,79,80"

        Do

            randomPosicionXY = CStr(Random.Next(11, 88))

            If nroNoValido.IndexOf(randomPosicionXY) > 0 Then
                encontrado = True
            Else
                encontrado = False
            End If


        Loop While encontrado = True
        Return randomPosicionXY

    End Function
    'A ver si esto hace que no se cuelgue cuando queremos insertar varios caballos
    Public Function randomIntento(ByRef lista As ArrayList) As String
        Dim R As Integer
        R = Random.Next(0, lista.Count)
        randomIntento = lista(R)
        lista.RemoveAt(R)
        Return CInt(randomIntento)
    End Function

#End Region

#Region "Random Cantidad de Pieza"
    Public Function randomCantidadPieza() As Byte
        Dim Random As New Random()
        Return Random.Next(1, 63)
    End Function
#End Region

#Region "Para los tableros"
    ''' <summary>
    ''' Compara dos tableros para verificar si son iguales o no.
    ''' </summary>
    ''' <param name="tablero1">Tablero 1</param>
    ''' <param name="tablero2">Tablero 2</param>
    ''' <returns>Devuelve "True" si son iguales y "False" si no lo son</returns>
    ''' <remarks></remarks>
    Public Function compararTableros(ByVal tablero1 As Tablero, ByVal tablero2 As Tablero) As Boolean
        For i As Integer = 1 To 8
            For j As Integer = 1 To 8
                If Not tablero1.obtenerFigura(i, j) = tablero2.obtenerFigura(i, j) Then
                    Return False
                End If
            Next
        Next
        Return True
    End Function
    ''' <summary>
    ''' Evalúa que tan bueno es la configuración del tablero actual.
    ''' </summary>
    ''' <param name="tableroAnterior">Es la configuración de tablero desde la cual se llego a la actual</param>
    ''' <param name="tableroActual">Es la configuración que se evalúa</param>
    ''' <param name="posCabN">Es la posición del caballo negro en el tablero actual</param>
    ''' <returns>Devuelve el valor que genera la heurística</returns>
    ''' <remarks></remarks>
    Public Function heuristica(ByVal tableroAnterior As Tablero, ByVal tableroActual As Tablero, ByVal posCabN As Integer) As Integer
        'Tabla(,) es la matriz que permite obtener la cantidad mínima de movimientos que el caballo negro necesita hacer para comer el caballo blano analizado
        Dim tabla(,) As Short = New Short(7, 7) {{0, 3, 2, 3, 2, 3, 4, 5}, {3, 4, 1, 2, 3, 4, 3, 4}, {2, 1, 4, 3, 2, 3, 4, 5}, {3, 2, 3, 2, 3, 4, 3, 4}, {2, 3, 2, 3, 4, 3, 4, 5}, {3, 4, 3, 4, 3, 4, 5, 4}, {4, 3, 4, 3, 4, 5, 4, 5}, {5, 4, 5, 4, 5, 4, 5, 6}}
        Dim distc, distf, movs, min, c, f, fila, col, cont As Integer
        min = 6
        fila = posCabN \ 10     '
        col = posCabN Mod 10    ' Se otiene la fila y la columna del caballo negro a partir de la posición que se manda
        cont = 0
        For n As Integer = 1 To 8       'Se recorre todo el tablero
            For m As Integer = 1 To 8
                If tableroAnterior.obtenerFigura(n, m) = "0" Then   'Se fija si la celda tiene un cuaballo blanco
                    c = m                                           '
                    f = n                                           'Obtiene la posición del caballo blanco
                    If c > col Then                                 'Otiene la distancia en columas entre el caballo negro y el blanco
                        distc = Math.Abs(c - col + 1)
                    Else
                        distc = Math.Abs(col - c + 1)
                    End If
                    If f > fila Then                                'Otiene la distancia en filas entre el caballo negro y el blanco
                        distf = Math.Abs(f - fila + 1)
                    Else
                        distf = Math.Abs(fila - f + 1)
                    End If
                    If (distc = 2 And distf = 2) And ((Not (c = 1 Or c = 8) And (f = 1 Or f = 8)) Or (Not (col = 1 Or col = 8) And (fila = 1 Or fila = 8))) Then
                        movs = 2
                    Else
                        movs = tabla((distf - 1), (distc - 1))      'Busca en la tabla el valor correspondiente a esa posición
                    End If
                    heuristica = heuristica + movs
                    If movs < min Then
                        min = movs                                  'Guarda la cantidad de movimientos mínima
                    End If
                End If
            Next
        Next
        heuristica = heuristica + min                               'Suma la cantidad de movimientos mínima a la sumatoria total
        Return heuristica
    End Function
#End Region

End Module
